﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web;
using System.Web.Routing;

namespace RedSand.Web.Mvc.Controls
{
    public static class RsPager
    {
        /// <summary>
        /// Html data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, PageSize=10, ButtonCount=7, PagerMode=PagerMode.NextPrevNumeric, RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int totalRecord)
        {
            return Pager(helper, 10, totalRecord, 7, PagerMode.NextPrevNumeric, null);
        }
        /// <summary>
        /// Html data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, PageSize=10, ButtonCount=7, PagerMode=PagerMode.NextPrevNumeric, HtmlAttribute=null}
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="routeValues">Tham số truy vấn</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int totalRecord, object routeValues)
        {
            return Pager(helper, 10, totalRecord, 7, PagerMode.NextPrevNumeric, routeValues);
        }
        /// <summary>
        /// Html data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode)
        {
            return Pager(helper, pageSize, totalRecord, buttonCount, pagerMode, null);
        }
        /// <summary>
        /// Html data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="routeValues">Tham số truy vấn</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, object routeValues)
        {
            string action = helper.ViewContext.RouteData.Values["action"].ToString().ToLower();
            string controller = helper.ViewContext.RouteData.Values["controller"].ToString().ToLower();
            return GeneratePager(helper, action, controller, "page", 1, pageSize, totalRecord, buttonCount, pagerMode, routeValues, null, null);
        }
        /// <summary>
        /// Html data pager - Default: { RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="action">Action</param>
        /// <param name="controller">Controller</param>
        /// <param name="queryKey">Từ khóa truy vấn trang</param>
        /// <param name="defaultPage">Trang mạc định</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, string action, string controller, string queryKey, int defaultPage, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode)
        {
            return GeneratePager(helper, action, controller, queryKey, defaultPage, pageSize, totalRecord, buttonCount, pagerMode, null, null, null);
        }
        /// <summary>
        /// Html data pager - Default: null
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="action">Action</param>
        /// <param name="controller">Controller</param>
        /// <param name="queryKey">Từ khóa truy vấn trang</param>
        /// <param name="defaultPage">Trang mạc định</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="routeValues">Tham số try vấn</param>
        /// <param name="htmlAttributes">Thuộc tính html</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this HtmlHelper helper, string action, string controller, string queryKey, int defaultPage, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, object routeValues, object htmlAttributes)
        {
            return GeneratePager(helper, action, controller, queryKey, defaultPage, pageSize, totalRecord, buttonCount, pagerMode, routeValues, htmlAttributes, null);
        }

        /// <summary>
        /// Ajax data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, PageSize=10, ButtonCount=7, PagerMode=PagerMode.NextPrevNumeric, RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, int totalRecord, AjaxOptions ajaxOptions)
        {
            return Pager(helper, 10, totalRecord, 7, PagerMode.NextPrevNumeric, ajaxOptions, null);
        }
        /// <summary>
        /// Ajax data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, PageSize=10, ButtonCount=7, PagerMode=PagerMode.NextPrevNumeric, HtmlAttribute=null}
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <param name="routeValues">Tham số truy vấn</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, int totalRecord, AjaxOptions ajaxOptions, object routeValues)
        {
            return Pager(helper, 10, totalRecord, 7, PagerMode.NextPrevNumeric, ajaxOptions, routeValues);
        }
        /// <summary>
        /// Ajax data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, AjaxOptions ajaxOptions)
        {
            return Pager(helper, pageSize, totalRecord, buttonCount, pagerMode, ajaxOptions, null);
        }
        /// <summary>
        /// Ajax data pager - Default: { Action={CurrentAction}, Controller={CurrentController}, QueryKey="page", DefaultPage=1, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <param name="routeValues">Tham số truy vấn</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, AjaxOptions ajaxOptions, object routeValues)
        {
            string action = helper.ViewContext.RouteData.Values["action"].ToString().ToLower();
            string controller = helper.ViewContext.RouteData.Values["controller"].ToString().ToLower();
            return GeneratePager(helper, action, controller, "page", 1, pageSize, totalRecord, buttonCount, pagerMode, routeValues, null, ajaxOptions);
        }
        /// <summary>
        /// Ajax data pager - Default: { RouteValues=null, HtmlAttribute=null }
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="action">Action</param>
        /// <param name="controller">Controller</param>
        /// <param name="queryKey">Từ khóa truy vấn trang</param>
        /// <param name="defaultPage">Trang mạc định</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, string action, string controller, string queryKey, int defaultPage, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, AjaxOptions ajaxOptions)
        {
            return GeneratePager(helper, action, controller, queryKey, defaultPage, pageSize, totalRecord, buttonCount, pagerMode, null, null, ajaxOptions);
        }
        /// <summary>
        /// Ajax data pager - Default: null
        /// </summary>
        /// <param name="helper">Html</param>
        /// <param name="action">Action</param>
        /// <param name="controller">Controller</param>
        /// <param name="queryKey">Từ khóa truy vấn trang</param>
        /// <param name="defaultPage">Trang mạc định</param>
        /// <param name="pageSize">Số bản ghi trên một trang</param>
        /// <param name="totalRecord">Tổng số bản ghi</param>
        /// <param name="buttonCount">Số lượng trang hiện thị trên button</param>
        /// <param name="pagerMode">Kiểu phân trang</param>
        /// <param name="ajaxOptions">AjaxOption</param>
        /// <param name="routeValues">Tham số try vấn</param>
        /// <param name="htmlAttributes">Thuộc tính html</param>
        /// <returns></returns>
        public static MvcHtmlString Pager(this AjaxHelper helper, string action, string controller, string queryKey, int defaultPage, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, AjaxOptions ajaxOptions, object routeValues, object htmlAttributes)
        {
            return GeneratePager(helper, action, controller, queryKey, defaultPage, pageSize, totalRecord, buttonCount, pagerMode, routeValues, htmlAttributes, ajaxOptions);
        }
       
        //base
        private static MvcHtmlString GeneratePager(object helper, string action, string controller, string queryKey, int defaultPage, int pageSize, int totalRecord, int buttonCount, PagerMode pagerMode, object routeValues, object htmlAttributes, AjaxOptions ajaxOptions)
        {
            string html = "", mode = pagerMode.ToString();
            pageSize = pageSize <= 0 ? 1 : pageSize;
            totalRecord = totalRecord < 0 ? 0 : totalRecord;
            int pageCount = totalRecord / pageSize + ((totalRecord % pageSize == 0) ? 0 : 1);
            if (pageCount < 2) return MvcHtmlString.Empty;

            queryKey = string.IsNullOrWhiteSpace(queryKey) ? "Page" : queryKey.Trim();

            int pageIndex = defaultPage;
            pageIndex = Convert.ToInt32(HttpContext.Current.Request.QueryString[queryKey]);
            pageIndex = pageIndex == 0 ? Convert.ToInt32(HttpContext.Current.Request.RequestContext.RouteData.Values[queryKey]) : pageIndex;
            pageIndex = pageIndex < 1 ? 1 : pageIndex;
            pageIndex = pageIndex > pageCount ? pageCount : pageIndex;

            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);

            RouteValueDictionary route=new RouteValueDictionary(routeValues);
            route.Add(queryKey, "PageIndex");
            string href = url.Action(action, controller, route);

            TagBuilder div = new TagBuilder("div");
            div.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            div.AddCssClass("rs-pager");

            TagBuilder hiddenLink = new TagBuilder("a");
            hiddenLink.Attributes["href"] = href;
            hiddenLink.Attributes["style"] = "display:none";
            if(ajaxOptions!=null) hiddenLink.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
            hiddenLink.Attributes["class"] = "rs-pager-hidden-link";

            html += hiddenLink.ToString();

            TagBuilder link = new TagBuilder("a");
            if (mode.Contains("First") || mode.Contains("Full"))
            {
                link.Attributes["class"] = "rs-pager-button-first";
                if (pageIndex == 1)
                {
                    link.Attributes["class"] += " rs-pager-button-disable";
                }
                link.Attributes["href"] = "1";
                link.SetInnerText("First");
                html += "\n" + link.ToString();
            }
            if (mode.Contains("Prev") || mode.Contains("Full"))
            {
                link.Attributes["class"] = "rs-pager-button-prev";
                if (pageIndex == 1)
                {
                    link.Attributes["class"] += " rs-pager-button-disable";
                    link.Attributes["href"] = "1";
                }
                else
                {
                    link.Attributes["href"] = (pageIndex - 1).ToString();
                }
                link.SetInnerText("Prev");
                html += "\n" + link.ToString();
            }
            if (mode.Contains("Numeric") || mode.Contains("Full"))
            {
                int firstIndex, lastIndex;
                firstIndex = pageIndex - buttonCount / 2 + (buttonCount % 2 == 0 ? 1 : 0);
                firstIndex = firstIndex < 1 ? 1 : firstIndex;
                lastIndex = buttonCount + firstIndex - 1;
                lastIndex = lastIndex > pageCount ? pageCount : lastIndex;
                firstIndex = lastIndex - buttonCount + 1;
                firstIndex = firstIndex < 1 ? 1 : firstIndex;

                for (int index = firstIndex; index <= lastIndex; index++)
                {
                    link.Attributes["class"] = "rs-pager-button-numeric";
                    if (index == pageIndex)
                    {
                        link.Attributes["class"] += " rs-pager-button-disable rs-pager-button-index";
                    }
                    link.Attributes["href"] = index.ToString();
                    link.SetInnerText(index.ToString());
                    html += "\n" + link.ToString();
                }
            }
            if (mode.Contains("Next") || mode.Contains("Full"))
            {
                link.Attributes["class"] = "rs-pager-button-next";
                if (pageIndex == pageCount)
                {
                    link.Attributes["class"] += " rs-pager-button-disable";
                    link.Attributes["href"] = pageCount.ToString();
                }
                else
                {
                    link.Attributes["href"] = (pageIndex + 1).ToString();
                }
                link.SetInnerText("Next");
                html += "\n" + link.ToString();
            }
            if (mode.Contains("Last") || mode.Contains("Full"))
            {
                link.Attributes["class"] = "rs-pager-button-last";
                if (pageIndex == pageCount)
                {
                    link.Attributes["class"] += " rs-pager-button-disable";
                }
                link.Attributes["href"] = pageCount.ToString();
                link.SetInnerText("Last");
                html += "\n" + link.ToString();
            }

            string script = "";
            script += @"
            <script type='text/javascript'>
                try{
                    $(function(){
                        $('.rs-pager a').not('.rs-pager-hidden-link').click(function(){
                            if($(this).is('.rs-pager-button-disable')) return false;
                            var link = $(this).parent().find('.rs-pager-hidden-link');
                            link.attr('href', link.attr('href').replace('PageIndex', $(this).attr('href')));
                            if(link.attr('data-ajax')=='true'){
                                link.click();
                            }
                            else{
                                location=link.attr('href');
                            }
                            return false;
                        });
                    });
                }
                catch(ex){
                    alert('Cần sử dụng thư viện jquery cho chức năng phân trang phân trang');
                }
            </script>";
            html += "\r\n" + script;
            div.InnerHtml = html;

            return MvcHtmlString.Create(div.ToString());

        }
    }

    public enum PagerMode
    {
        NumericOnly = 1,
        FisrtLastNextPrev = 2,
        FisrtLastNumeric = 3,
        NextPrevNumeric = 4,
        FullMode = 5,
    }
}
